package com.nexus.all.service.impl;

import com.nexus.all.constants.RedisKeyNexus;
import com.nexus.all.dto.LoginBodyDTO;
import com.nexus.all.dto.UserUpdateDTO;
import com.nexus.all.dto.excel.UserExcelData;
import com.nexus.all.listener.excel.UserCheckListener;
import com.nexus.all.manager.UserManager;
import com.nexus.all.model.User;
import com.nexus.all.service.UserService;
import com.nexus.all.vo.UserVO;
import com.nexus.bean.enums.CommonStatusEnum;
import com.nexus.bean.exeption.ServiceException;
import com.nexus.bean.model.UserInfoVO;
import com.nexus.bean.result.ResultCode;
import com.nexus.bean.utils.BeanUtils;
import com.nexus.bean.utils.PasswordEncoderUtil;
import com.nexus.bean.utils.StringUtils;
import com.nexus.bean.utils.TrueUtils;
import com.nexus.redis.utils.RedisUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author zxt
 */
@Slf4j
@Service
@AllArgsConstructor
public class UserServiceImpl implements UserService {

    private final PasswordEncoderUtil passwordEncoderUtil;
    private final UserManager userManager;

    @Override
    public UserInfoVO login(LoginBodyDTO dto) {
        User user = userManager.getByUserName(dto.getUsername());
        if (Objects.isNull(user)) {
            // 用户不存在
            throw new ServiceException(ResultCode.LOGIN_ERROR);
        }
        boolean matches = passwordEncoderUtil.matches(dto.getPassword(), user.getUserPwd());
        if (!matches) {
            throw new ServiceException(ResultCode.USER_PWD_ERROR);
        }
        if (CommonStatusEnum.DISABLE.equal(user.getUserStatus())) {
            throw new ServiceException(ResultCode.USER_DISABLE_ERROR);
        }
        return BeanUtils.beanCopy(user, UserInfoVO.class);
    }

    @Override
    public void updateById(User user) {
        userManager.updateById(user);
    }

    @Override
    public UserVO getById(Long id) {
        User user = userManager.getById(id);
        if (Objects.isNull(user)) {
            throw new ServiceException(ResultCode.COMMON_MESSAGE, "用户不存在");
        }
        UserVO userVO = BeanUtils.beanCopy(user, UserVO.class);
        return userVO;
    }

    @Override
    public List<UserVO> getAllUser() {
        List<User> userList = userManager.list();
        return BeanUtils.beanCopy(userList, UserVO.class);
    }

    @Override
    public UserInfoVO mobileLogin(LoginBodyDTO dto) {
        if (StringUtils.isEmpty(dto.getUsername())) {
            throw new ServiceException(ResultCode.COMMON_MESSAGE, "请输入手机号");
        }
        if (StringUtils.isEmpty(dto.getCode())) {
            throw new ServiceException(ResultCode.COMMON_MESSAGE, "请输入验证码");
        }
        Object o = RedisUtil.get(RedisKeyNexus.getMobileCaptchaKey(dto.getUsername()));
        if (Objects.isNull(o)) {
            throw new ServiceException(ResultCode.COMMON_MESSAGE, "验证码错误");
        }
        if (!o.toString().equals(dto.getCode())) {
            throw new ServiceException(ResultCode.COMMON_MESSAGE, "验证码错误");
        }

        User existUser = userManager.getByUserName(dto.getUsername());
        if (Objects.isNull(existUser)) {
            //不存在，新建
            existUser = new User();
            existUser.setUserName(dto.getUsername());
            existUser.setUserPwd(passwordEncoderUtil.encode(dto.getUsername()));
            existUser.setPhone(dto.getUsername());
            existUser.setAvatarUrl("https://copywritings.oss-accelerate.aliyuncs.com/boot/nexus-all/images/2024-02-26/082b83b7885348c8b6e1d8a4a9bba551.png");
            existUser.setNickName(dto.getUsername());
            existUser.setUserStatus(CommonStatusEnum.ENABLE.getValue());
            userManager.save(existUser);
        } else {
            if (CommonStatusEnum.DISABLE.equal(existUser.getUserStatus())) {
                throw new ServiceException(ResultCode.USER_DISABLE_ERROR);
            }
        }
        return BeanUtils.beanCopy(existUser, UserInfoVO.class);
    }

    @Override
    public void updatePassword(UserUpdateDTO dto) {
        User user = userManager.getById(dto.getUserId());

        TrueUtils.isTrue(Objects.isNull(user)).throwMessage("用户不存在");

        boolean isTrue = passwordEncoderUtil.matches(dto.getOldPassword(), user.getUserPwd());

        TrueUtils.isTrue(!isTrue).throwMessage("旧密码错误");

        TrueUtils.isTrue(dto.getOldPassword().equals(dto.getPassword())).throwMessage("新密码不能和旧密码一致");

        userManager.updatePassword(dto.getUserId(), dto.getPassword());
    }

    @Override
    public void updateAvatar(UserUpdateDTO dto) {
        userManager.updateAvatar(dto.getUserId(), dto.getAvatarUrl());
        //因为所以用户信息都会缓存在redis一份，所以当用户信息变更时，需要清除缓存，来达到数据一致性
        RedisUtil.delete(RedisKeyNexus.ALL_USER_INFO);
    }

    @Override
    public void updateNameEmail(UserUpdateDTO dto) {
        userManager.updateNickNameAndEmail(dto.getUserId(), dto.getNickName(), dto.getEmail());
    }

    @Override
    public void checkImportData(List<UserExcelData> excelDataList, UserCheckListener userCheckListener, Long userId) {

        List<String> userNames = excelDataList.stream().map(UserExcelData::getUsername).collect(Collectors.toList());
        List<User> userList = userManager.getByUserNames(userNames);
        Map<String, User> existUserMap = userList.stream().collect(Collectors.toMap(User::getUserName, Function.identity()));

        for (UserExcelData userExcelData : excelDataList) {
            User existUser = existUserMap.get(userExcelData.getUsername());
            if (Objects.nonNull(existUser)) {
                userCheckListener.getErrorList().add("第" + userExcelData.getRowIndex() + "行: 用户名已存在");
            }

            if (StringUtils.isNotBlank(userExcelData.getPassword())) {
                if (userExcelData.getPassword().length() < 6 || userExcelData.getPassword().length() > 12) {
                    userCheckListener.getErrorList().add("第" + userExcelData.getRowIndex() + "行: 密码需要大于6位并且小于12位");
                }
            }
        }
    }

    @Override
    public void importData(List<UserExcelData> excelDataList, Long userId) {
        List<User> userList = new ArrayList<>();
        for (UserExcelData data : excelDataList) {
            User user = new User();
            user.setUserName(data.getUsername());
            user.setUserPwd(passwordEncoderUtil.encode(data.getPassword()));
            user.setPhone(data.getUsername());
            user.setAvatarUrl("https://copywritings.oss-accelerate.aliyuncs.com/boot/nexus-all/images/2024-02-26/082b83b7885348c8b6e1d8a4a9bba551.png");
            user.setNickName(data.getUsername());
            user.setUserStatus(CommonStatusEnum.ENABLE.getValue());
            userList.add(user);
        }
        userManager.saveBatch(userList);
    }
}
